/* 
 * $Id: tailq.h 7557b5d4d82b 2012/12/02 09:07:16 pgurumur $
 *
 * Copyright (c) 2006, 2007, 2008 Prabhu Gurumurthy <pgurumur@gmail.com>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef __PY_TAILQ_H_
#define __PY_TAILQ_H_

#include <sys/types.h>
/* Queue header where all types of queues are present */
#include <sys/queue.h>

/*
 * Essential c headers
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
 * Essential python headers
 */
#include <Python.h>
#include <listobject.h>
#include <structmember.h>


/*
 * Bunch of defines for alloc, free
 */
#define TQ_MEMBER(object) struct PyMemberDef object
#define TQ_MEMBER_LIST(a,b,c,d,e) { a, b, c, d, e }
#define TQ_ALLOC(object, type) (object *)type.tp_alloc(&type, 0)
#define TQ_FREE(object) object->ob_type->tp_free((PyObject *)ob)

enum TailQ_ValueType {
   INVALID = -1,
   BOOLEAN = 0,
   DICTIONARY,
   FLOAT,
   INTEGER,
   LIST,
   LONG,
   STRING,
   TUPLE,
   UNICODE,
};

struct tailq {
   TAILQ_ENTRY(tailq) entries;
   PyObject *key;
   PyObject *value;
   enum TailQ_ValueType type;
};

typedef struct {
   PyObject_HEAD
   PyObject *converter;
   TAILQ_HEAD(_tq_head, tailq) PyTailQ_Head;
   int count;
   int closed;
} PyTailQ_Object;

static PyObject *PyTailQ_Error;
extern PyTypeObject PyTailQ_ObjectType;

const char *_PyTailQ_Version = "0.1";
static char _PyTailQ_Doc[] = "TAILQ in python";

void inittailq(void);

static void _PyTailQ_Object_DeAlloc(PyTailQ_Object *);
static int _PyTailQ_Traverse(PyTailQ_Object *, visitproc, void *);
static int _PyTailQ_SetAttr(PyTailQ_Object *, char *, PyObject *);
static PyObject *_PyTailQ_GetAttr(PyTailQ_Object *, char *);
static PyObject *PyTailQ_Delete(PyTailQ_Object *, PyObject *);

/* utility functions */
static int CheckValueType(PyObject *);

/* method functions */
static PyObject *PyTailQ_Init(PyObject *, PyObject *);
static PyObject *PyTailQ_Add(PyTailQ_Object *, PyObject *);
static PyObject *PyTailQ_Delete(PyTailQ_Object *, PyObject *);
static PyObject *PyTailQ_List(PyTailQ_Object *, PyObject *);
static PyObject *PyTailQ_Close(PyTailQ_Object *, PyObject *);

static PyMethodDef PyTailQ_Methods[] = {
   {
      "init",
      (PyCFunction)PyTailQ_Init,
      METH_NOARGS,
      NULL
   },
   {
      "add",
      (PyCFunction)PyTailQ_Add,
      METH_VARARGS,
      NULL
   },
   {
      "delete",
      (PyCFunction)PyTailQ_Delete,
      METH_VARARGS,
      NULL
   },
   {
      "list",
      (PyCFunction)PyTailQ_List,
      METH_NOARGS,
      NULL
   },
   { NULL, NULL, 0, NULL },
};

static TQ_MEMBER(_PyTailQ_ObjectMemberList)[] = {
   TQ_MEMBER_LIST(
         "converter", T_OBJECT, offsetof(PyTailQ_Object, converter), RO,
         "Type conversion mapping"),
   { NULL, 0, 0, 0, NULL }
};

#endif
